package chttp

import (
	"gitee.com/cooge/impush/core"
	"gitee.com/cooge/impush/message"
	user2 "gitee.com/cooge/impush/user"
	"gitee.com/cooge/impush/util"
	"gitee.com/cooge/impush/xhttp/user"
	"net"
	"strconv"
	"strings"
	"time"
)

type CHttpConn struct {
	user.HttpConn
	blankNum int
}

var endbyte = []byte("\r\n0\r\n\r\n")

var kkbytes = []byte("\r\n")

var nlankbyte = []byte("\r\n1\r\n ")

var blankBytes = []byte(`[]`)

func NewCHttpConn(conn net.Conn) *CHttpConn {
	return &CHttpConn{HttpConn: user.HttpConn{UserLite: &user2.UserLite{UserTCPConn: conn, Type: message.HTTP, Local: true}}}
}

func (ch *CHttpConn) Start(dealTime int, livetime int, userId string, cnc user.CallNewConnFunc) {
	ch.UserId = userId
	ch.CreateTime = util.GetNowTime()
	ch.Deadline = dealTime
	ch.LiveTime = livetime + livetime
	ch.HttpConn.HttpConnWrite = ch.write
	ch.HttpConn.HttpConnFlush = ch.Flush
	ch.header()
	go ch.read()
	cnc(ch)

}

func (ch *CHttpConn) Flush() {
	if ch.IsTimeOut() {
		core.DeleteUser(ch.UserId, &ch.HttpConn)
	} else {
		if !ch.IsBreak() {
			ch.WriteBlank()
		}
	}
}

var headerBytes = []byte("HTTP/1.1 200 OK\r\n" +
	"Content-Type: text/html;charset=UTF-8\r\n" +
	"Content-Language: zh\r\n" +
	"Access-Control-Allow-Origin: *\r\n" +
	"Transfer-Encoding: chunked\r\n")

func (this *CHttpConn) header() {
	this.Write(headerBytes)
	this.WriteBlank()
}
func (ch *CHttpConn) read() {
	ch.Add()
	da := make([]byte, 1)
	ch.UserTCPConn.Read(da)
	ch.Close(ch.UserId)
}
func (ch *CHttpConn) end() {
	ch.Write(endbyte)
	ch.UserTCPConn.Close()
}

func (ch *CHttpConn) WriteBlank() {
	ch.blankNum--
	ch.Write(nlankbyte)
	ch.SetReadDeadline()
	if ch.blankNum == 0 {
		ch.write(blankBytes)
	}

}

func (ch *CHttpConn) SetReadDeadline() {
	ch.UserTCPConn.SetDeadline(time.Now().Add(time.Duration(ch.LiveTime) * time.Second))
}

func (ch *CHttpConn) write(data []byte) (int, error) {
	da := make([]byte, 0)
	da = append(da, kkbytes...)
	ln := len(data)
	slen := []byte(strings.ToUpper(strconv.FormatInt((int64)(ln), 16)))
	da = append(da, slen...)
	da = append(da, kkbytes...)
	da = append(da, data...)
	da = append(da, endbyte...)
	_, err := ch.Write(da)
	if err != nil {
		ch.Close(ch.UserId)
		return 0, err
	}
	ch.Close(ch.UserId)
	return ln, nil
}
